<script setup>
import { computed, onMounted, onUnmounted, ref, watchEffect } from 'vue';
import createStorage from '../utils/createStorage';

const storage = createStorage('TODOS');

const todos = ref(storage.getItem() || []);

// 监听todos的变化，将结果存到localStorage
watchEffect(() => {
  storage.setItem(todos.value);
});

const input = ref('');

// 添加代办事项
const addTodo = () => {
  const text = input.value?.trim();
  
  if (!text) return;

  todos.value.unshift({
    text,
    completed: false
  });

  input.value = '';
};

// 删除代办事项
const remove = (todo) => {
  const index = todos.value.indexOf(todo);
  todos.value.splice(index, 1);
};

const removeCompleted = () => {
  todos.value = todos.value.filter(todo => !todo.completed);
};

// 编辑待办事项
let beforeText = '';               // 编辑前的文本
const editingTodo = ref(null);     // 正在编辑的项

const editTodo = (todo) => {
  beforeText = todo.text;
  editingTodo.value = todo;
};

const doneEdit = (todo) => {
  // 没有编辑，不往下执行
  if (!editingTodo.value) return;

  todo.text = todo.text.trim();

  // 不存在内容，则直接删除
  if (!todo.text) {
    remove(todo);
  }

  editingTodo.value = null;
};

const cancelEdit = (todo) => {
  todo.text = beforeText;
  editingTodo.value = null;
};

// 切换代办事项
const allDone = computed({
  get() {
    return todos.value.every(todo => todo.completed);
  },
  set(value) {
    todos.value.filter(todo => todo.completed = value);
  }
});

// 监听hash变化
// type到转换函数的映射
const filters = {
  all: list => list,
  active: list => list.filter(item => !item.completed),
  completed: list => list.filter(item => item.completed),
};

const type = ref('all');

// 监听type、todos的变化，获取到转换函数并调用
const filterTodos = computed(() => filters[type.value](todos.value));

// 监听todos变化，获取到代办事项个数
const count = computed(() => todos.value.length);

// 监听todos变化，获取到活动的代办事项个数
const remainingCount = computed(() => filters.active(todos.value).length);

// hashchange后的处理函数
const handleChange = () => {
  const hash = window.location.hash.replace('#/', '');
  if (filters[hash]) {
    type.value = hash;
  } else {
    type.value = 'all';
    window.location.hash = '';
  }
};

// 监听hashchange
onMounted(() => {
  window.addEventListener('hashchange', handleChange);
  handleChange();
});

// 移除hashchange
onUnmounted(() => {
  window.removeEventListener('hashchange', handleChange);
});
</script>

<script>
import '../assets/index.css';

export default {
  directives: {
    editingFocus: (el, binding) => {
      binding.value && el.focus();
    }
  }
}
</script>

<template>
  <section id="app" class="todoapp">
    <header class="header">
      <h1>todos</h1>
      <input
        class="new-todo"
        placeholder="What needs to be done?"
        autocomplete="off"
        autofocus
        v-model="input"
        @keyup.enter="addTodo"
      />
    </header>
    <section class="main" v-show="count">
      <input id="toggle-all" class="toggle-all" type="checkbox" v-model="allDone" />
      <label for="toggle-all">Mark all as complete</label>
      <ul class="todo-list">
        <li
          v-for="(todo, index) in filterTodos"
          :key="index"
          :class="{ editing: todo === editingTodo, completed: todo.completed }"
        >
          <div class="view">
            <input class="toggle" type="checkbox" v-model="todo.completed" />
            <label @dblclick="editTodo(todo)">{{ todo.text }}</label>
            <button class="destroy" @click="remove(todo)"></button>
          </div>
          <input
            class="edit"
            type="text"
            v-editing-focus="editingTodo === todo"
            v-model="todo.text"
            @keyup.enter="doneEdit(todo)"
            @blur="doneEdit(todo)"
            @keyup.esc="cancelEdit(todo)"
          />
        </li>
      </ul>
    </section>
    <footer class="footer" v-show="count">
      <span class="todo-count">
        <strong>{{ remainingCount }}</strong> {{ remainingCount > 1 ? 'items' : 'item' }} left
      </span>
      <ul class="filters">
        <li><a href="#/all">All</a></li>
        <li><a href="#/active">Active</a></li>
        <li><a href="#/completed">Completed</a></li>
      </ul>
      <button class="clear-completed" @click="removeCompleted" v-show="count > remainingCount">
        Clear completed
      </button>
    </footer>
  </section>
  <footer class="info">
    <p>Double-click to edit a todo</p>
    <!-- Remove the below line ↓ -->
    <p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p>
    <!-- Change this out with your name and url ↓ -->
    <p>Created by <a href="https://www.lagou.com">教瘦</a></p>
    <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
  </footer>
</template>

<style scoped>
a {
  color: #42b983;
}
</style>
